
#include <stdio.h>
#include <string.h>

char rfc3986[256] = {0};

char hex[] = "0123456789ABCDEF";

void url_encode_init()
{
    int i;
    for (i = 0; i < sizeof(rfc3986); i++)
    {
        switch (i)
        {
        case '0' ... '9':
        case 'A' ... 'Z':
        case 'a' ... 'z':
        case '-':
        case '.':
        case '_':
        case '~':
            rfc3986[i] = i;
        }
    }
}

//返回编码之后的字节数
size_t url_encode(const unsigned char * src, size_t src_len, char * dst, size_t dst_len)
{
    char* c = dst;
    int i;
    for (i = 0; i < src_len; i++)
    {
        if (c + 3 > dst + dst_len)
        {
            break;
        }
        if (rfc3986[src[i]])
        {
            *c = rfc3986[src[i]];
            c++;
        }
        else
        {
            c[0] = '%';
            c[1] = hex[src[i] >> 4];
            c[2] = hex[src[i] & 0xf];
            c += 3;
        }
    }

    return c - dst;
}

int main()
{
    char* s = "编码";
    char output[13] = {0};
    url_encode_init();
    size_t n = url_encode((unsigned char*)s, strlen(s), output, sizeof output);
    printf("encode: %zd\n", n);
    puts(output);
}
